package com.shawn.springboot.integeration.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.shawn.springboot.integeration.common.constant.UserConstants;
import com.shawn.springboot.integeration.common.exception.BusinessException;
import com.shawn.springboot.integeration.common.util.text.Convert;
import com.shawn.springboot.integeration.system.mapper.SysPostMapper;
import com.shawn.springboot.integeration.system.mapper.SysRoleMapper;
import com.shawn.springboot.integeration.system.mapper.SysUserMapper;
import com.shawn.springboot.integeration.system.mapper.SysUserPostMapper;
import com.shawn.springboot.integeration.system.mapper.SysUserRoleMapper;
import com.shawn.springboot.integeration.system.model.pojo.SysPost;
import com.shawn.springboot.integeration.system.model.pojo.SysRole;
import com.shawn.springboot.integeration.system.model.pojo.SysUser;
import com.shawn.springboot.integeration.system.model.pojo.SysUserPost;
import com.shawn.springboot.integeration.system.model.pojo.SysUserRole;
import com.shawn.springboot.integeration.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangjian
 * @description: 用户信息服务
 * @date 2022/8/21
 */
@Service
public class SysUserServiceImpl implements ISysUserService {
    private static Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);
    @Resource
    private SysUserMapper userMapper;

    @Resource
    private SysRoleMapper roleMapper;

    @Resource
    private SysPostMapper postMapper;

    @Resource
    private SysUserPostMapper userPostMapper;

    @Resource
    private SysUserRoleMapper userRoleMapper;

    @Override
    public List<SysUser> selectUserList(SysUser user) {
        return userMapper.selectUserList(user);
    }

    @Override
    public List<SysUser> selectAllocatedList(SysUser user) {
        return userMapper.selectAllocatedList(user);
    }

    @Override
    public List<SysUser> selectUnallocatedList(SysUser user) {
        return userMapper.selectUnallocatedList(user);
    }

    @Override
    public SysUser selectUserByLoginName(String userName) {
        return userMapper.selectUserByLoginName(userName);
    }

    @Override
    public SysUser selectUserByPhoneNumber(String phoneNumber) {
        return userMapper.selectUserByPhoneNumber(phoneNumber);
    }

    @Override
    public SysUser selectUserByEmail(String email) {
        return userMapper.selectUserByEmail(email);
    }

    @Override
    public SysUser selectUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }

    @Override
    public List<SysUserRole> selectUserRoleByUserId(Long userId) {
        return userRoleMapper.selectUserRoleByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserById(Long userId) {
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);

        // 删除用户与岗位表
        userPostMapper.deleteUserPostByUserId(userId);

        // 删除用户信息
        return userMapper.deleteUserById(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserByIds(String ids) {
        Long[] userIds = Convert.toLongArray(ids);

        // 检查账号是否允许修改
        for (Long userId : userIds) {
            checkUserAllowed(new SysUser(userId));
        }

        // 删除用户与角色关联
        userRoleMapper.deleteUserRole(userIds);

        // 删除用户与岗位关联
        userPostMapper.deleteUserPost(userIds);

        // 删除用户信息
        return userMapper.deleteUserByIds(userIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUser(SysUser user) {
        // 新增用户信息
        int rows = userMapper.insertUser(user);

        // 新增用户与岗位关联
        insertUserPost(user);

        // 新增用户与角色关联
        insertUserRole(user.getUserId(), user.getRoleIds());
        return rows;
    }

    @Override
    public boolean registerUser(SysUser user) {
        user.setUserType(UserConstants.REGISTER_USER_TYPE);
        return userMapper.insertUser(user) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateUser(SysUser user) {
        Long userId = user.getUserId();

        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);

        // 新增用户与角色关联
        insertUserRole(userId, user.getRoleIds());

        // 删除用户与岗位关联
        userPostMapper.deleteUserPostByUserId(userId);

        // 新增用户与岗位关联
        insertUserPost(user);

        // 更新用户信息
        return userMapper.updateUser(user);
    }

    @Override
    public int updateUserInfo(SysUser user) {
        return userMapper.updateUser(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUserAuth(Long userId, Long[] roleIds) {
        // 删除用户角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);

        // 插入用户角色关联
        insertUserRole(userId, roleIds);
    }

    @Override
    public int resetUserPwd(SysUser user) {
        return userMapper.updateUser(user);
    }

    @Override
    public String checkLoginNameUnique(String loginName) {
        int count = userMapper.checkLoginNameUnique(loginName);
        if (count > 0) {
            return UserConstants.USER_NAME_NOT_UNIQUE;
        }
        return UserConstants.USER_NAME_UNIQUE;
    }

    @Override
    public String checkPhoneUnique(SysUser user) {
        Long userId = null == user.getUserId() ? -1L : user.getUserId();
        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
        if (null != info && !info.getUserId().equals(userId)) {
            return UserConstants.USER_PHONE_NOT_UNIQUE;
        }
        return UserConstants.USER_PHONE_UNIQUE;
    }

    @Override
    public String checkEmailUnique(SysUser user) {
        Long userId = null == user.getUserId() ? -1L : user.getUserId();
        SysUser info = userMapper.checkEmailUnique(user.getEmail());
        if (null != info && !info.getUserId().equals(userId)) {
            return UserConstants.USER_EMAIL_NOT_UNIQUE;
        }
        return UserConstants.USER_EMAIL_UNIQUE;
    }

    @Override
    public void checkUserAllowed(SysUser user) {
        if (null != user.getUserId() && user.isAdmin()) {
            throw new BusinessException("不允许操作超级管理员用户");
        }
    }

    @Override
    public String selectUserRoleGroup(Long userId) {
        List<SysRole> list = roleMapper.selectRolesByUserId(userId);
        if (CollectionUtil.isEmpty(list)) {
            return StrUtil.EMPTY;
        }
        return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
    }

    @Override
    public String selectUserPostGroup(Long userId) {
        List<SysPost> list = postMapper.selectPostsByUserId(userId);
        if (CollectionUtil.isEmpty(list)) {
            return StrUtil.EMPTY;
        }
        return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
    }

    /**
     * 新增用户与岗位信息
     *
     * @param user 用户信息
     */
    public void insertUserPost(SysUser user) {
        Long[] postIds = user.getPostIds();
        if (null != postIds && postIds.length > 0) {
            List<SysUserPost> list = new ArrayList<>();
            for (Long postId : postIds) {
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(postId);
                list.add(up);
            }

            if (list.size() > 0) {
                userPostMapper.batchUserPost(list);
            }
        }
    }

    /**
     * 插入用户角色关联信息
     *
     * @param userId  用户 ID
     * @param roleIds 角色 ID 集合
     */
    public void insertUserRole(Long userId, Long[] roleIds) {
        if (null != roleIds && roleIds.length > 0) {
            List<SysUserRole> userRoleList = new ArrayList<>();
            for (Long roleId : roleIds) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                userRoleList.add(userRole);
            }

            if (CollectionUtil.isNotEmpty(userRoleList)) {
                userRoleMapper.batchUserRole(userRoleList);
            }
        }
    }
}
